package com.hup.restTimer.view.main;

import com.hup.restTimer.model.AppConfig;
import com.hup.restTimer.view.rest.RestWindow;
import com.hup.utils.commons.exception.AppExceptionHandler;
import com.hup.utils.commons.hardware.ScreenUtil;
import com.hup.utils.commons.start.StartupInfo;
import com.hup.utils.swing.FrameUtil;
import com.hup.utils.swing.customView.ImageLabel;
import com.hup.utils.swing.frame.BaseJWindow;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.swing.JLayeredPane;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

/**
 * 主窗口
 * .鼠标穿透
 * .显示[文本提醒]
 * .关联显示 {@link RestWindow}
 *
 * @author hugan
 * @date 2022/10/1
 */
@Slf4j
public class MainWindow extends BaseJWindow {

    private final AppConfig config;
    @Getter
    private final RestWindow restWindow;
    @Getter
    private TipsLabel tipsLabel;
    @Getter
    private ImageLabel backgroundLabel;

    private boolean inited;

    /**
     * 有无鼠标穿透的属性值
     */
    private int windowStyleDefault, windowStylePenetration;
    private boolean isPenetration;

    public MainWindow(AppConfig config) {
        super(StartupInfo.getApplicationChName());
        this.config = config;
        restWindow = new RestWindow(config);

        initView();
        inited = true;
    }

    private void initView() {
        try {
            int[] res = FrameUtil.setMousePenetration(this);
            windowStyleDefault = res[0];
            windowStylePenetration = res[1];
            log.debug("defaultWindow=[{}, {}]", windowStyleDefault, windowStylePenetration);
        } catch (Exception e) {
            config.notSupportPenetration = true;
            AppExceptionHandler.handle("不支持鼠标穿透,", e);
        }
        isPenetration = true;

        setAlwaysOnTop(true);
        Dimension screenSize = ScreenUtil.getScreenSize();
        screenSize.width -= 2;//四周留间隙,避免可能影响自动隐藏的window状态栏
        screenSize.height -= 2;
        setSize(screenSize);
        setLocation(1, 1);

        //添加图层
        MyJLayeredPane root = new MyJLayeredPane();
        setContentPane(root);
        //背景图 图层
        backgroundLabel = new ImageLabel();
        backgroundLabel.setBackground(new Color(0, 0, 0, 1));//近似透明的背景色,避免"图片的透明像素,使鼠标穿透"
        backgroundLabel.setVisible(false);
        root.add(backgroundLabel, new Integer(0));
        //提醒文本 图层
        tipsLabel = new TipsLabel(config);
        root.add(tipsLabel, new Integer(1));

        setBackground(new Color(0, 0, 0, 0));//背景透明
        FrameUtil.setAlpha(this, 0.999f);//整个窗口是"接近不透明的",
    }

    @Override
    public void dispose() {
        /*
        解决诡异问题
            .推测是swing对[异步线程,嵌套创建窗口实例]的内部处理机制
            .new MainWindow 方法中 new RestWindow, 线程=RestTimerAsync
            .MainWindow.dispose会被框架代码调用, 线程=AWT-EventQueue-0
         */
        //log.info("dispose");
        if (inited) super.dispose();//父类的dispose会 SingletonWindowHelper.removeWindow导致程序业务异常
    }

    @Override
    public void setVisible(boolean b) {
        boolean old = isVisible();
        if (old == b) return;
        if (b && inited) {//初始化时, tipsLabel为null
            tipsLabel.updateTimeStr();
        }
        super.setVisible(b);
        if (inited) restWindow.switchVisible(b);
        log.info("setVisible={}", b);
    }

    /**
     * 切换鼠标穿透效果
     *
     * @param b true-鼠标穿透
     */
    public void setPenetration(boolean b) {
        if (isPenetration == b) return;
        try {
            //log.info("穿透={}", b);
            /*
            问题
                直接setWindowStyles,窗口会变黑屏!
                目前无明确原因,未深究
            目前方案:切换Visible时,可以'解决问题'
             */
            boolean visibleOld = isVisible();
            setVisible(false);
            FrameUtil.setWindowStyles(this, b ? windowStylePenetration : windowStyleDefault);
            if (visibleOld) setVisible(true);
        } catch (Exception e) {
            AppExceptionHandler.handle("切换状态异常,", e);
        }
        isPenetration = b;
    }

    private static class MyJLayeredPane extends JLayeredPane {
        @Override
        public void setBounds(int x, int y, int width, int height) {
            super.setBounds(x, y, width, height);
            for (Component child : getComponents()) {
                child.setBounds(0, 0, width, height);
            }
        }
    }

}
